package com.youlu.campus.web.user.controller;

import com.alibaba.fastjson.JSON;
import com.youlu.campus.base.exception.BusinessException;

import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.SubTemplateSceneConfig;
import com.youlu.campus.entity.UserPO;
import com.youlu.campus.entity.VO.req.CheckMobileVO;
import com.youlu.campus.entity.VO.req.UserInviteCreateVO;
import com.youlu.campus.entity.VO.req.WechatH5CodeReqNewVo;
import com.youlu.campus.entity.VO.req.WechatH5CodeReqVO;
import com.youlu.campus.entity.VO.res.ActivityInfoLogoRes;
import com.youlu.campus.entity.VO.res.UserResponse;
import com.youlu.campus.entity.WechatMiniUserPO;
import com.youlu.campus.entity.domain.WechatMiniDecryptRequest;
import com.youlu.campus.entity.douyin.dto.DouYinMiniDecryptDTO;
import com.youlu.campus.entity.douyin.dto.UserLoginDTO;
import com.youlu.campus.entity.enums.TaskBizType;
import com.youlu.campus.entity.platform.PlatformSubConfigure;
import com.youlu.campus.service.activity.ActivityService;
import com.youlu.campus.service.activity.ActivitySubscribeAppIdService;
import com.youlu.campus.service.activity.SubTemplateSceneConfigService;
import com.youlu.campus.service.cache.CacheActivityService;
import com.youlu.campus.service.douyin.DouYinUserService;
import com.youlu.campus.service.h5.H5UserPOService;
import com.youlu.campus.service.platform.AppUrlLinkService;
import com.youlu.campus.service.platform.PlatformSubConfigureService;
import com.youlu.campus.service.qq.QQMiniUserService;
import com.youlu.campus.service.utils.WebTokenUtils;
import com.youlu.campus.service.visitor.VisitorUserService;
import com.youlu.campus.service.wechat.WechatMiniService;
import com.youlu.campus.service.wechat.WechatThirdUserService;
import com.youlu.campus.web.client.QQTokenService;
import com.youlu.campus.web.common.base.RequestContext;
import com.youlu.campus.web.config.aspect.ResponseResultBodyType;
import com.youlu.campus.web.user.dto.request.DecryptRequest;
import com.youlu.campus.web.user.service.UserService;
import com.youlu.campus.web.user.service.impl.QQUserService;
import com.yuelin.infrastructure.quantum.common.QResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;

/**
 * 用户信息
 *
 * @author: zhuhuaqii
 * @date: 2021/02/23
 */
@Slf4j
@RestController
@ResponseResultBodyType
public class LoginController {

    @Autowired
    private UserService userService;
    @Autowired
    private VisitorUserService visitorUserService;
    @Autowired
    private ActivityService activityService;

    @Autowired
    private QQUserService qqUserService;

    @Lazy
    @Autowired
    private QQTokenService qqTokenService;
    @Autowired
    private WechatMiniService wechatMiniService;
    @Autowired
    private WechatThirdUserService wechatThirdUserService;

    @Autowired
    private H5UserPOService h5UserPOService;

    @Autowired
    private CacheActivityService cacheActivityService;

    @Autowired
    private QQMiniUserService qqMiniUserService;

    @Autowired
    private SubTemplateSceneConfigService subTemplateSceneConfigService;

    @Autowired
    private AppUrlLinkService appUrlLinkService;

    @Autowired
    private DouYinUserService douYinUserService;

    @Autowired
    private PlatformSubConfigureService platformSubConfigureService;

    @Autowired
    private ActivitySubscribeAppIdService activitySubscribeAppIdService;

    @GetMapping("/")
    @ResponseBody
    public QResult root() {
        return QResult.success("你好，路游校园。2021年2月23日.");
    }

    /**
     * QQ小程序登陆登录
     *
     * @param code
     * @param appId
     * @return
     */
    @RequestMapping("/public/mini-app/qq/login")
    public UserResponse parseToken(@RequestParam("code") String code,
                                   @RequestParam(value = "appId", required = false) String appId) {
        UserResponse userResponse = qqMiniUserService.qqMiniLogin(code, appId);
        return userResponse;
    }

    @GetMapping("/public/activity/logo")
    public QResult getActivityAuthorizeLogo(@RequestParam(value = "activityId") String activityId,
                                            @RequestParam(value = "appId", required = false) String appId,
                                            @RequestParam(value = "platform", required = false) String platform,
                                            @RequestParam(value = "bizType", required = false) TaskBizType bizType,
                                            @RequestParam(value = "miniAppId", required = false) String miniAppId) {
        // 默认梦想跳动的小程序
        if (StringUtils.isBlank(miniAppId)) {
            miniAppId = "wxc3211a2e49489560";
        }
        ActivityInfo activityInfo = cacheActivityService.findById(activityId);
        if (Objects.isNull(activityInfo)) {
            throw new BusinessException("活动不存在,尽情期待!");
        }
        String subscribeAppId = activitySubscribeAppIdService.getActivitySubscribeAppIdByActivityId(activityId);
        ActivityInfoLogoRes activityInfoLogo = new ActivityInfoLogoRes();
        activityInfoLogo.setSubscribeAppId(subscribeAppId);
        activityInfoLogo.setWechatAuthorizationDesc(activityInfo.getWechatAuthorizationDesc());
        activityInfoLogo.setWechatAuthorizationImageUrl(activityInfo.getWechatAuthorizationImageUrl());
        PlatformSubConfigure platformSubConfigure = platformSubConfigureService.findByAppId(subscribeAppId);
        log.info("获取平台配置订阅信息->{}", JSON.toJSON(platformSubConfigure));
        if (Objects.isNull(platformSubConfigure)) {
            log.error(":>>> 警告警告，公众号:{} 消息订阅没有配置:{}", appId, "严重警告!!!!");
//            throw new BusinessException("平台正在维护中!请联系客服");
        }
        if (Objects.isNull(platformSubConfigure)) {
            activityInfoLogo.setSubOpen(false);
        } else {
            activityInfoLogo.setSubOpen(platformSubConfigure.getSubOpen());
        }
        activityInfoLogo.setChinaWebsite(activityInfo.getChinaWebsite());
        if (StringUtils.isNotBlank(subscribeAppId)) {
            appId = subscribeAppId;
        }
        if (activityInfoLogo.getSubOpen()) {
            SubTemplateSceneConfig subTemplateSceneConfig = subTemplateSceneConfigService.findByTemplateIdAndActivityId(appId, platform, bizType, activityId);
            if (Objects.nonNull(subTemplateSceneConfig)) {
                activityInfoLogo.setScene(subTemplateSceneConfig.getScene());
                activityInfoLogo.setTemplateId(subTemplateSceneConfig.getTemplateId());
            }
        }
        activityInfoLogo.setUrlLink(appUrlLinkService.getUrlLink(miniAppId));
        return QResult.success(activityInfoLogo);
    }

    /**
     * QQ小程序解密用户信息
     *
     * @param request
     * @return
     */
    @RequestMapping("/public/mini-app/decrypt")
    public UserPO decrypt(@RequestBody DecryptRequest request) {
        return userService.decrypt(request);
    }

    /**
     * QQ小程序解密用户信息
     *
     * @param request
     * @return
     */
    @RequestMapping("/mini-app/decrypt")
    public UserPO qqDecrypt(@RequestBody DecryptRequest request) {
        return userService.decrypt(request);
    }

    /**
     * wechat H5授权接口
     *
     * @param req
     * @return
     */
    @PostMapping("/public/wechat-h5/code")
    public QResult getWechatH5Code(@RequestBody WechatH5CodeReqVO req) {
        log.info(":>>> 开始获取Code H5:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId()) || StringUtils.isBlank(req.getAppId()) || Objects.isNull(req.getType())) {
            log.error(":>>> 获取Code 参数错误:活动ID,应用ID、类型为空");
            throw new BusinessException("获取Code 参数错误:活动ID,应用ID、类型为空");
        }
        String codeUrl = userService.getWechatH5CodeByAppId(req);
        log.info(":>>> 获取Code:{}", codeUrl);
        return QResult.success(codeUrl);
    }

    @PostMapping("/public/wechat-h5/code/new")
    public QResult getWechatH5CodeNew(@RequestBody WechatH5CodeReqNewVo req) {
        log.info(":>>> 开始获取Code H5:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getAppId())) {
            log.error(":>>> 获取Code 参数错误:活动ID,应用ID、类型为空");
            throw new BusinessException("获取Code 参数错误:活动ID,应用ID、类型为空");
        }
        String codeUrl = userService.getWechatH5CodeUrlByAppId(req);
        log.info(":>>> 获取Code:{}", codeUrl);
        return QResult.success(codeUrl);
    }

    @PostMapping("/public/h5/authorize/code")
    public QResult getAuthorizeCode(@RequestBody WechatH5CodeReqVO req) {
        if (Objects.isNull(req) || StringUtils.isBlank(req.getAppId())) {
            log.error(":>>> 获取Code 参数错误:活动ID,应用ID、类型为空");
            throw new BusinessException("获取Code 参数错误:活动ID,应用ID、类型为空");
        }
        String codeUrl = userService.authorizeCode(req);
        log.info(":>>> 获取Code:{}", codeUrl);
        return QResult.success(codeUrl);
    }

    /**
     * 微信H5登陆
     *
     * @param req
     * @param code
     * @param activityId
     * @param appId
     * @param platform
     * @param type
     * @param scope
     * @param rewardType
     * @param extension
     * @param version
     * @return
     */
    @PostMapping("/public/wechat-h5/login")
    public QResult getWechatH5AccessToken(@RequestBody(required = false) UserInviteCreateVO req, @RequestParam("code") String code, @RequestParam("activityId") String activityId,
                                          @RequestParam("appId") String appId,
                                          @RequestParam("platform") String platform,
                                          @RequestParam("type") Integer type,
                                          @RequestParam(defaultValue = "snsapi_userinfo", value = "scope") String scope,
                                          @RequestParam(defaultValue = "0", value = "rewardType") Integer rewardType,
                                          @RequestParam(value = "extension", required = false) String extension,
                                          @RequestParam(value = "version", required = false) String version) {
        log.info(">>> 登陆接口携带的code:{},appId:{},activityId:{},platform:{},scope->{}", code, appId, activityId, platform, scope);
        UserResponse res = userService.getWechatH5AccessToken(code, appId, activityId, type, scope, rewardType, extension, version);
        this.createInvite(req, platform, appId, activityId, res.getUserPO());
        res.setAuthorizeMode("wechat");
        return QResult.success(res);
    }

    @PostMapping("/public/h5-english/login")
    public QResult getWechatH5Login(@RequestBody(required = false) UserInviteCreateVO req,
                                    @RequestParam("activityId") String activityId,
                                    @RequestParam("code") String code,
                                    @RequestParam("appId") String appId,
                                    @RequestParam("platform") String platform,
                                    @RequestParam(value = "extension", required = false) String extension) {
        log.info(">>> 登陆接口携带的code:{},appId:{},platform:{}", code, appId, platform);
        UserResponse res = userService.getWechatH5AccessToken(code, appId, activityId, 999, "snsapi_userinfo", 0, extension, "");
        this.createInvite(req, platform, appId, activityId, res.getUserPO());
        res.setAuthorizeMode("wechat");
        return QResult.success(res);
    }

    @PostMapping("/public/qq-h5/authorize")
    public QResult qqAuthorize(@RequestBody WechatH5CodeReqVO req) {
        if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId()) || StringUtils.isBlank(req.getAppId()) || Objects.isNull(req.getType())) {
            log.error(":>>> 获取Code 参数错误:活动ID,应用ID、类型为空");
            throw new BusinessException("获取Code 参数错误:活动ID,应用ID、类型为空");
        }
        return QResult.success(qqTokenService.authorizeCode(req));
    }

    /**
     * qqH5登陆
     *
     * @param req
     * @param code
     * @param activityId
     * @param appId
     * @param platform
     * @param type
     * @return
     */
    @PostMapping("/public/qq-h5/login")
    public QResult getQQH5AccessToken(@RequestBody(required = false) UserInviteCreateVO req,
                                      @RequestParam("code") String code, @RequestParam("activityId") String activityId,
                                      @RequestParam("appId") String appId, @RequestParam("platform") String platform,
                                      @RequestParam("type") Integer type) {
        log.info(">>> 登陆接口携带的code:{},appId:{},activityId:{},platform:{},<<<<", code, appId, activityId, platform);
        UserResponse res = qqUserService.getQQH5AccessToken(code, appId, activityId, type);
        this.createInvite(req, platform, appId, activityId, res.getUserPO());
        res.setAuthorizeMode("qq");
        return QResult.success(res);
    }

    @PostMapping("/public/h5/login")
    public QResult h5Login(@RequestBody CheckMobileVO req) {
        com.youlu.campus.entity.domain.UserResponse response = h5UserPOService.codeLogin(req);
        if (StringUtils.isBlank(response.getToken())) {
            response.setToken(WebTokenUtils.signToken(response.getOpenId()));
            response.setAuthorizeMode("sms");
            response.setMobile(req.getMobile());
        }
        return QResult.success(response);
    }

    /**
     * App登陆
     *
     * @param req
     * @param code
     * @param activityId
     * @param appId
     * @param platform
     * @param type
     * @return
     */
    @PostMapping("/public/app/login")
    public QResult appLogin(@RequestBody(required = false) UserInviteCreateVO req,
                            @RequestParam("code") String code, @RequestParam("activityId") String activityId,
                            @RequestParam("appId") String appId, @RequestParam("platform") String platform,
                            @RequestParam("type") Integer type) {
        log.info(">>> 登陆接口携带的code:{},appId:{},activityId:{},platform:{},<<<<", code, appId, activityId, platform);
        UserResponse res = qqUserService.getQQH5AccessToken(code, appId, activityId, type);
        this.createInvite(req, platform, appId, activityId, res.getUserPO());
        return QResult.success(res);
    }

    /**
     * 微信小程序登陆
     *
     * @param appId
     * @param code
     * @return
     */
    @RequestMapping("/public/wechat-mini/login")
    public UserResponse wechatMiniProgramLogin(@RequestHeader(value = "appId") String headerAppId, @RequestParam(value = "appId", required = false) String appId, @RequestParam("code") String code) {
        if (StringUtils.isBlank(appId)) {
            appId = headerAppId;
        }
        UserResponse userResponse = wechatMiniService.login(appId, code);
        return userResponse;
    }

    /**
     * 解密微信小程序数据
     *
     * @param request
     * @return
     */
    @PostMapping("/mini-app/wechat/decrypt")
    public WechatMiniUserPO decrypt(@RequestBody WechatMiniDecryptRequest request) {
        return wechatMiniService.decryptUserData(request, RequestContext.getCurUser());
    }

    /**
     * 绑定手机号,目前只针对微信小程序
     *
     * @param req
     * @return
     */
    @PostMapping("/mini-app/wechat-mini/bind-mobile")
    public QResult mobileCode(@RequestBody CheckMobileVO req) {
        log.info(":>>> 手机号验证码登陆:{}", JSON.toJSON(req));
        if (StringUtils.isAnyBlank(req.getMobile(), req.getCode())) {
            throw new BusinessException("手机号或验证码错误");
        }
        req.setUserPO(RequestContext.getCurUser());
        UserResponse res = wechatMiniService.bindMobile(req);
        return QResult.success(res);
    }

    /**
     * 抖音小程序登陆
     *
     * @return
     */
    @PostMapping("/public/douyin-mini/login")
    public QResult douyinMiniProgramLogin(@RequestBody UserLoginDTO dto) {
        log.info("dou yin param:{}", dto);
        return QResult.success(douYinUserService.login(dto));
    }

    /**
     * 解密微信小程序数据
     *
     * @param request
     * @return
     */
    @PostMapping("/mini-app/douyin/decrypt")
    public QResult douyinDecrypt(@RequestBody DouYinMiniDecryptDTO request) {
        request.setUserPO(RequestContext.getCurUser());
        return QResult.success(douYinUserService.decryptUserData(request));
    }

    /**
     * 手机验证码登陆
     */
    @PostMapping("/public/login/code")
    public UserResponse codeLogin(@RequestBody CheckMobileVO req) {
        return userService.codeLogin(req);
    }

    /**
     * 微信第三方登陆
     *
     * @param appId
     * @param code
     * @return
     */
    @RequestMapping("/public/wechat-third/login")
    public UserResponse wechatThirdLogin(@RequestParam("appId") String appId, @RequestParam("code") String code) {
        UserResponse userResponse = wechatThirdUserService.login(appId, code);
        return userResponse;
    }

    @PostMapping("/public/wechat-third/code")
    public QResult getwechatThirdLoginCode(@RequestBody WechatH5CodeReqVO req) {
        if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId()) || StringUtils.isBlank(req.getAppId()) || Objects.isNull(req.getType())) {
            log.error(":>>> 获取Code 参数错误:活动ID,应用ID、类型为空");
            throw new BusinessException("获取Code 参数错误:活动ID,应用ID、类型为空");
        }
        String codeUrl = wechatThirdUserService.getwechatThirdLoginCode(req);
        log.info(":>>> 获取微信第三方授权Code:{}", codeUrl);
        return QResult.success(codeUrl);
    }

    @Async
    public void createInvite(UserInviteCreateVO req, String platform, String appId, String activityId, UserPO userPO) {
        try {
            if (Objects.nonNull(req)) {
                UserPO invitedByUser = null;
                switch (platform) {
                    case "qq-h5":
                        invitedByUser = visitorUserService.getUser(platform, appId, req.getSharedByOpenId());
                        break;
                    case "qq":
                        invitedByUser = visitorUserService.getUserByOpenId(req.getSharedByOpenId());
                        break;
                    case "wechat-h5":
                        invitedByUser = visitorUserService.getUser(platform, appId, req.getSharedByOpenId());
                        break;
                    default:
                        break;
                }
                if (Objects.nonNull(userPO)) {
                    req.setInvitedByUserInfo(invitedByUser);
                    req.setTargetOpenId(userPO.getOpenId());
                    req.setTargetUser(userPO);
                    req.setPlatform(platform);
                    req.setAppId(appId);
                    req.setActivityId(activityId);
                    activityService.createActivityInvite(req);
                }
            }
        } catch (BusinessException e) {
            log.error(":>>> 登陆创建分享错误:{}", e.getMessage());
        } catch (Exception e) {
            log.error(":>>> 登陆创建分享错误:{}", e);
        }
    }
}
